/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ru.miit.elearning.vtutor.check.object;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import ru.miit.elearning.vtutor.check.CheckObjectResult;
import ru.miit.elearning.vtutor.data.CheckObject;
import ru.miit.elearning.vtutor.ftp.FTPClientDecorator;
import ru.miit.elearning.vtutor.wsclient.VlStudent;

/**
 *
 * @author Cyclone
 */
public class CheckObjectFileType extends AbstractCheckObject {

    private static final boolean DEBUG = false, SHOW_RESULT = false;

    CheckObjectFileType(CheckObject co) {
        super(co);
    }

    @Override
    public CheckObjectResult check(VlStudent student, FTPClientDecorator ftp) {
        CheckObjectResult cor = new CheckObjectResult();

        JSONObject jsonCheck = null;
        OutputStream os = null;

        try {
            jsonCheck = new JSONObject();

            String home = student.getZOSHomeFolder();
            path = path.replace("<userid>", home);
            if (home.indexOf("/") == 0) {
                path = home + "/" + path;
            } else {
                path = "/" + home + "/" + path;
            }

            jsonCheck.put("path", path);
            jsonCheck.put("type", type);

            os = new ByteArrayOutputStream();
            boolean fileFound = ftp.retrieveFile(path, os);

            if (!fileFound) {
                return getNotFoundCheckDetails(cor, jsonCheck);
            } else {
                // file found
                if ((content != null) && !(content.length == 0) && !((content.length == 1)
                        && (content[0].equals("null") || content[0].equals("")))) {
                    // need to check content

                    String fileContent = ((ByteArrayOutputStream) os).toString();

                    boolean fileChecked = true;
                    jsonCheck.put("status", AbstractCheckObject.STATUS_FOUND_AND_CHECKING);
                    JSONArray jsonCombs = new JSONArray();
                    for (int i = 0; i < content.length; i++) {
                        JSONObject jsonComb = new JSONObject();
                        content[i] = content[i].replaceAll("<userid>", student.getZOSHomeFolder());
                        jsonComb.put("comb", content[i]);

                        if (content[i].toLowerCase().equals("<notnull>")) {
                            if (fileContent.length() > 0) {
                                // --- fileDetails.append("\nФайл не пуст.");
                                jsonComb.put("check", AbstractCheckObject.COMB_FOUND);
                            } else {
                                fileChecked = false;
                                // --- fileDetails.append("\nФайл пуст.");
                                jsonComb.put("check", AbstractCheckObject.COMB_NOT_FOUND);

                                // TODO Should break checking cycle if checked = false ?
                                // break;
                            }
                        } else {
                            // if(!contentString.matches(".*" + content[i] + ".*"))
                            //if (fileContent.indexOf(content[i]) != -1) {
                            if (fileContent.contains(content[i])) {
                                // --- fileDetails.append("\nКомбинация \"" + content[i] + "\" найдена.");
                                jsonComb.put("check", AbstractCheckObject.COMB_FOUND);
                                if (DEBUG) {
                                    System.out.println("\tCombination \"" + content[i] + "\" found.");
                                }
                            } else {
                                // --- fileDetails.append("\nНе найдена комбинация \"" + content[i] + "\".");
                                jsonComb.put("check", AbstractCheckObject.COMB_NOT_FOUND);
                                fileChecked = false;
                                if (DEBUG) {
                                    System.out.println("\tCombination \"" + content[i] + "\" not found.");
                                }

                                // TODO Should break checking cycle if checked = false ?
                                // break;
                            }
                        }
                        jsonCombs.put(jsonComb);
                    }
                    jsonCheck.put("combs", jsonCombs);
                    // file found and content checked

                    // --- fileDetails.append("\nФайл " + (fileChecked ? "" : "не ") + "засчитан.");
                    jsonCheck.put("result", fileChecked ? AbstractCheckObject.RESULT_CHECK_OK : AbstractCheckObject.RESULT_CHECK_FAILED);

                    if (SHOW_RESULT) {
                        System.out.println("\tSHOW_RESULT: File \"" + path + "\"" + (fileChecked ? "" : " not") + " checked");
                    }

                    cor.setChecked(fileChecked);
                    // --- cor.setDetails(fileDetails.toString());
                    cor.setDetails(jsonCheck);
                    return cor;

                } else {
                    // file found, no need to check content

                    // --- fileDetails.append("\nФайл \"" + path + "\" найден.");
                    // --- fileDetails.append("\nФайл засчитан.");

                    jsonCheck.put("status", AbstractCheckObject.STATUS_FOUND);
                    jsonCheck.put("result", AbstractCheckObject.RESULT_CHECK_OK);

                    if (SHOW_RESULT) {
                        System.out.println("\tSHOW_RESULT: File \"" + path + "\" found");
                    }

                    cor.setChecked(true);
                    // --- cor.setDetails(fileDetails.toString());
                    cor.setDetails(jsonCheck);
                    return cor;
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
            try {
                jsonCheck.put("status", AbstractCheckObject.STATUS_EXCEPTION);
                jsonCheck.put("result", AbstractCheckObject.RESULT_CHECK_FAILED);
            } catch (JSONException ex) {
                Logger.getLogger(CheckObjectFileType.class.getName()).log(Level.SEVERE, null, ex);
            }


            if (SHOW_RESULT) {
                System.out.println("\tSHOW_RESULT: File \"" + path + "\" not checked found due to Exception");
            }

            cor.setChecked(false);
            // --- cor.setDetails(fileDetails.toString());
            cor.setDetails(jsonCheck);
            return cor;

        } finally {
            if (os != null) {
                try {
                    os.close();
                } catch (Exception e) {
                    System.err.println("Failed to close OutputStream: " + e.getMessage());
                }
            }
        }
    }

    @Override
    public String getTextContent(FTPClientDecorator ftp) {
        OutputStream os = null;
        String textContent = null;
        try {
            os = new ByteArrayOutputStream();
            if (ftp.retrieveFile(path, os)) {
                textContent = os.toString();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (os != null) {
                try {
                    os.close();
                } catch (IOException ex) {
                    System.err.println(ex.getMessage());
                    Logger.getLogger(CheckObjectFileType.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
        return textContent;
    }
}
